
namespace Behemoth.Web.UI.WebControls {

    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.IO;

	public class SafeRenderer {

		public SafeRenderer() {
			_exceptions = new List<Exception>();
			_buffer = new StringBuilder();
			_writer = new StringWriter( _buffer ); // this is where we store our attempt to render a control
			_htmlwriter = new HtmlTextWriter( _writer );
		}

		private List<Exception> _exceptions;
		public List<Exception> Exceptions {
			get { return _exceptions; }
		}

		private StringBuilder _buffer;
		private StringWriter _writer;
		private HtmlTextWriter _htmlwriter;

		/// <summary>
		/// Render your control to this writer so it will be buffered in case of errors.
		/// </summary>
		public HtmlTextWriter BufferedWriter {
			get { return _htmlwriter; }
		}

		// assumes you already populated Writer with the text you want to render.
		public void RenderControl( HtmlTextWriter liveWriter ) {
#if DEBUG
			bool doTrace = true;
#else
			bool doTrace = false;
#endif
			if (this.Exceptions.Count > 0)
				// Output buffer since no exception occurred.
				TraceAndWriteErrors( liveWriter, doTrace );
			else {
				this.BufferedWriter.Close();
				liveWriter.Write( this._buffer.ToString() );
			}
		}

		private void TraceAndWriteErrors( HtmlTextWriter liveWriter, bool doTrace ) {
			string exHeading = string.Format( "Field Control rendering for {0} failed.", this.GetType().FullName );
			if (doTrace) {
				Trace.WriteLine( exHeading );
				Trace.WriteLine( HttpContext.Current.Request.Url.ToString() );
			}
			liveWriter.WriteBeginTag( "div" );
			liveWriter.WriteAttribute( "style", "color: black; border: solid 1px black; background-color: white; padding: 2px" );
			liveWriter.Write( ">" );
			liveWriter.WriteBeginTag( "b" );
			liveWriter.WriteAttribute( "style", "color: red" );
			liveWriter.Write( ">" );
			liveWriter.WriteLine( exHeading );
			liveWriter.WriteEndTag( "b" );
			liveWriter.WriteBreak();
			foreach (Exception ex in this.Exceptions) {
				if (doTrace)
					Trace.Write( ex );
				liveWriter.WriteFullBeginTag( "li" );
				liveWriter.WriteFullBeginTag( "b" );
				liveWriter.WriteLine( ex.Message );
				liveWriter.WriteEndTag( "b" );
#if DEBUG
				liveWriter.WriteBreak();
				liveWriter.WriteLine( ex.StackTrace );
#endif
				liveWriter.WriteEndTag( "li" );
			}
			liveWriter.WriteEndTag( "div" );
		}

	} // class

} // namesapce
